1 module discord_game_sdk;
2 
3 import core.stdc.string : memset;
4 
5 extern (C) @nogc nothrow:
6 
7 enum DISCORD_VERSION = 3;
8 enum DISCORD_APPLICATION_MANAGER_VERSION = 1;
9 enum DISCORD_USER_MANAGER_VERSION = 1;
10 enum DISCORD_IMAGE_MANAGER_VERSION = 1;
11 enum DISCORD_ACTIVITY_MANAGER_VERSION = 1;
12 enum DISCORD_RELATIONSHIP_MANAGER_VERSION = 1;
13 enum DISCORD_LOBBY_MANAGER_VERSION = 1;
14 enum DISCORD_NETWORK_MANAGER_VERSION = 1;
15 enum DISCORD_OVERLAY_MANAGER_VERSION = 2;
16 enum DISCORD_STORAGE_MANAGER_VERSION = 1;
17 enum DISCORD_STORE_MANAGER_VERSION = 1;
18 enum DISCORD_VOICE_MANAGER_VERSION = 1;
19 enum DISCORD_ACHIEVEMENT_MANAGER_VERSION = 1;
20 
21 enum DiscordResult
22 {
23     Ok = 0,
24     ServiceUnavailable = 1,
25     InvalidVersion = 2,
26     LockFailed = 3,
27     InternalError = 4,
28     InvalidPayload = 5,
29     InvalidCommand = 6,
30     InvalidPermissions = 7,
31     NotFetched = 8,
32     NotFound = 9,
33     Conflict = 10,
34     InvalidSecret = 11,
35     InvalidJoinSecret = 12,
36     NoEligibleActivity = 13,
37     InvalidInvite = 14,
38     NotAuthenticated = 15,
39     InvalidAccessToken = 16,
40     ApplicationMismatch = 17,
41     InvalidDataUrl = 18,
42     InvalidBase64 = 19,
43     NotFiltered = 20,
44     LobbyFull = 21,
45     InvalidLobbySecret = 22,
46     InvalidFilename = 23,
47     InvalidFileSize = 24,
48     InvalidEntitlement = 25,
49     NotInstalled = 26,
50     NotRunning = 27,
51     InsufficientBuffer = 28,
52     PurchaseCanceled = 29,
53     InvalidGuild = 30,
54     InvalidEvent = 31,
55     InvalidChannel = 32,
56     InvalidOrigin = 33,
57     RateLimited = 34,
58     OAuth2Error = 35,
59     SelectChannelTimeout = 36,
60     GetGuildTimeout = 37,
61     SelectVoiceForceRequired = 38,
62     CaptureShortcutAlreadyListening = 39,
63     UnauthorizedForAchievement = 40,
64     InvalidGiftCode = 41,
65     PurchaseError = 42,
66     TransactionAborted = 43,
67     DrawingInitFailed = 44,
68 }
69 
70 enum DiscordCreateFlags
71 {
72     Default = 0,
73     NoRequireDiscord = 1,
74 }
75 
76 enum DiscordLogLevel
77 {
78     Error = 1,
79     Warn,
80     Info,
81     Debug,
82 }
83 
84 enum DiscordUserFlag
85 {
86     Partner = 2,
87     HypeSquadEvents = 4,
88     HypeSquadHouse1 = 64,
89     HypeSquadHouse2 = 128,
90     HypeSquadHouse3 = 256,
91 }
92 
93 enum DiscordPremiumType
94 {
95     None = 0,
96     Tier1 = 1,
97     Tier2 = 2,
98 }
99 
100 enum DiscordImageType
101 {
102     User,
103 }
104 
105 enum DiscordActivityPartyPrivacy
106 {
107     Private = 0,
108     Public = 1,
109 }
110 
111 enum DiscordActivityType
112 {
113     Playing,
114     Streaming,
115     Listening,
116     Watching,
117 }
118 
119 enum DiscordActivityActionType
120 {
121     Join = 1,
122     Spectate,
123 }
124 
125 enum DiscordActivitySupportedPlatformFlags
126 {
127     Desktop = 1,
128     Android = 2,
129     iOS = 4,
130 }
131 
132 enum DiscordActivityJoinRequestReply
133 {
134     No,
135     Yes,
136     Ignore,
137 }
138 
139 enum DiscordStatus
140 {
141     Offline = 0,
142     Online = 1,
143     Idle = 2,
144     DoNotDisturb = 3,
145 }
146 
147 enum DiscordRelationshipType
148 {
149     None,
150     Friend,
151     Blocked,
152     PendingIncoming,
153     PendingOutgoing,
154     Implicit,
155 }
156 
157 enum DiscordLobbyType
158 {
159     Private = 1,
160     Public,
161 }
162 
163 enum DiscordLobbySearchComparison
164 {
165     LessThanOrEqual = -2,
166     LessThan,
167     Equal,
168     GreaterThan,
169     GreaterThanOrEqual,
170     NotEqual,
171 }
172 
173 enum DiscordLobbySearchCast
174 {
175     String = 1,
176     Number,
177 }
178 
179 enum DiscordLobbySearchDistance
180 {
181     Local,
182     Default,
183     Extended,
184     Global,
185 }
186 
187 enum DiscordKeyVariant
188 {
189     Normal,
190     Right,
191     Left,
192 }
193 
194 enum DiscordMouseButton
195 {
196     Left,
197     Middle,
198     Right,
199 }
200 
201 enum DiscordEntitlementType
202 {
203     Purchase = 1,
204     PremiumSubscription,
205     DeveloperGift,
206     TestModePurchase,
207     FreePurchase,
208     UserGift,
209     PremiumPurchase,
210 }
211 
212 enum DiscordSkuType
213 {
214     Application = 1,
215     DLC,
216     Consumable,
217     Bundle,
218 }
219 
220 enum DiscordInputModeType
221 {
222     VoiceActivity = 0,
223     PushToTalk,
224 }
225 
226 // types
227 alias DiscordClientId = long;
228 alias DiscordVersion = int;
229 alias DiscordSnowflake = long;
230 alias DiscordTimestamp = long;
231 alias DiscordUserId = DiscordSnowflake;
232 alias DiscordLocale = char[128];
233 alias DiscordBranch = char[4096];
234 alias DiscordLobbyId = DiscordSnowflake;
235 alias DiscordLobbySecret = char[128];
236 alias DiscordMetadataKey = char[256];
237 alias DiscordMetadataValue = char[4096];
238 alias DiscordNetworkPeerId = ulong;
239 alias DiscordNetworkChannelId = ubyte;
240 alias DiscordPath = char[4096];
241 alias DiscordDateTime = char[64];
242 
243 version (Posix)
244 {
245     alias IDXGISwapChain = void*;
246     alias MSG = void*;
247 }
248 
249 struct DiscordUser
250 {
251     DiscordUserId id;
252     char[256] username;
253     char[8] discriminator;
254     char[128] avatar;
255     bool bot;
256 }
257 
258 struct DiscordOAuth2Token
259 {
260     char[128] accessToken;
261     char[1024] scopes;
262     DiscordTimestamp expires;
263 }
264 
265 struct DiscordImageHandle
266 {
267     DiscordImageType type;
268     long id;
269     uint size;
270 }
271 
272 struct DiscordImageDimensions
273 {
274     uint width;
275     uint height;
276 }
277 
278 struct DiscordActivityTimestamps
279 {
280     DiscordTimestamp start;
281     DiscordTimestamp end;
282 }
283 
284 struct DiscordActivityAssets
285 {
286     char[128] largeImage;
287     char[128] largeText;
288     char[128] smallImage;
289     char[128] smallText;
290 }
291 
292 struct DiscordPartySize
293 {
294     int currentSize;
295     int maxSize;
296 }
297 
298 struct DiscordActivityParty
299 {
300     char[128] id;
301     DiscordPartySize size;
302     DiscordActivityPartyPrivacy privacy;
303 }
304 
305 struct DiscordActivitySecrets
306 {
307     char[128] match;
308     char[128] join;
309     char[128] spectate;
310 }
311 
312 struct DiscordActivity
313 {
314     DiscordActivityType type;
315     long applicationId;
316     char[128] name;
317     char[128] state;
318     char[128] details;
319     DiscordActivityTimestamps timestamps;
320     DiscordActivityAssets assets;
321     DiscordActivityParty party;
322     DiscordActivitySecrets secrets;
323     bool instance;
324     uint supportedPlatforms;
325 }
326 
327 struct DiscordPresence
328 {
329     DiscordStatus status;
330     DiscordActivity activity;
331 }
332 
333 struct DiscordRelationship
334 {
335     DiscordRelationshipType type;
336     DiscordUser user;
337     DiscordPresence presence;
338 }
339 
340 struct DiscordLobby
341 {
342     DiscordSnowflake id;
343     DiscordLobbyType type;
344     DiscordUserId ownerId;
345     char[128] secret;
346     uint capacity;
347     bool locked;
348 }
349 
350 struct DiscordImeUnderline
351 {
352     int from;
353     int to;
354     uint color;
355     uint backgroundColor;
356     bool thick;
357 }
358 
359 struct DiscordRect
360 {
361     int left;
362     int top;
363     int right;
364     int bottom;
365 }
366 
367 struct DiscordFileStat
368 {
369     char[260] filename;
370     ulong size;
371     ulong last_modified;
372 }
373 
374 struct DiscordEntitlement
375 {
376     DiscordSnowflake id;
377     DiscordEntitlementType type;
378     DiscordSnowflake skuId;
379 }
380 
381 struct DiscordSkuPrice
382 {
383     uint amount;
384     char[16] currency;
385 }
386 
387 struct DiscordSku
388 {
389     DiscordSnowflake id;
390     DiscordSkuType type;
391     char[256] name;
392     DiscordSkuPrice price;
393 }
394 
395 struct DiscordInputMode
396 {
397     DiscordInputModeType type;
398     char[256] shortcut;
399 }
400 
401 struct DiscordUserAchievement
402 {
403     DiscordSnowflake userId;
404     DiscordSnowflake achievementId;
405     ubyte percentComplete;
406     DiscordDateTime unlockedAt;
407 }
408 
409 struct IDiscordLobbyTransaction
410 {
411     private
412     {
413         DiscordResult function(IDiscordLobbyTransaction*, DiscordLobbyType) set_typeFunc;
414         DiscordResult function(IDiscordLobbyTransaction*, DiscordUserId) set_ownerFunc;
415         DiscordResult function(IDiscordLobbyTransaction*, uint) set_capacityFunc;
416         DiscordResult function(IDiscordLobbyTransaction*, DiscordMetadataKey, DiscordMetadataValue) set_metadataFunc;
417         DiscordResult function(IDiscordLobbyTransaction*, DiscordMetadataKey) delete_metadataFunc;
418         DiscordResult function(IDiscordLobbyTransaction*, bool) set_lockedFunc;
419     }
420 
421     DiscordResult setType(DiscordLobbyType type)
422     {
423         return set_typeFunc(&this, type);
424     }
425 
426     DiscordResult setOwner(DiscordUserId ownerId)
427     {
428         return set_ownerFunc(&this, ownerId);
429     }
430 
431     DiscordResult setCapacity(uint capacity)
432     {
433         return set_capacityFunc(&this, capacity);
434     }
435 
436     DiscordResult setMetadata(DiscordMetadataKey key, DiscordMetadataValue value)
437     {
438         return set_metadataFunc(&this, key, value);
439     }
440 
441     DiscordResult deleteMetadata(DiscordMetadataKey key)
442     {
443         return delete_metadataFunc(&this, key);
444     }
445 
446     DiscordResult setLocked(bool locked)
447     {
448         return set_lockedFunc(&this, locked);
449     }
450 }
451 
452 struct IDiscordLobbyMemberTransaction
453 {
454     private
455     {
456         DiscordResult function(IDiscordLobbyMemberTransaction*, DiscordMetadataKey, DiscordMetadataValue) set_metadataFunc;
457         DiscordResult function(IDiscordLobbyMemberTransaction*, DiscordMetadataKey) delete_metadataFunc;
458     }
459 
460     DiscordResult setMetadata(DiscordMetadataKey key, DiscordMetadataValue value)
461     {
462         return set_metadataFunc(&this, key, value);
463     }
464 
465     DiscordResult deleteMetadata(DiscordMetadataKey key)
466     {
467         return delete_metadataFunc(&this, key);
468     }
469 }
470 
471 struct IDiscordLobbySearchQuery
472 {
473     private
474     {
475         DiscordResult function(IDiscordLobbySearchQuery*, DiscordMetadataKey, DiscordLobbySearchComparison, DiscordLobbySearchCast, DiscordMetadataValue) filterFunc;
476         DiscordResult function(IDiscordLobbySearchQuery*, DiscordMetadataKey, DiscordLobbySearchCast, DiscordMetadataValue) sortFunc;
477         DiscordResult function(IDiscordLobbySearchQuery*, uint) limitFunc;
478         DiscordResult function(IDiscordLobbySearchQuery*, DiscordLobbySearchDistance) distanceFunc;
479     }
480 
481     DiscordResult filter(DiscordMetadataKey key, DiscordLobbySearchComparison comparison, DiscordLobbySearchCast searchCast, DiscordMetadataValue value)
482     {
483         return filterFunc(&this, key, comparison, searchCast, value);
484     }
485 
486     DiscordResult sort(DiscordMetadataKey key, DiscordLobbySearchCast searchCast, DiscordMetadataValue value)
487     {
488         return sortFunc(&this, key, searchCast, value);
489     }
490 
491     DiscordResult limit(uint limit)
492     {
493         return limitFunc(&this, limit);
494     }
495 
496     DiscordResult distance(DiscordLobbySearchDistance searchDistance)
497     {
498         return distanceFunc(&this, searchDistance);
499     }
500 }
501 
502 alias IDiscordApplicationEvents = void*;
503 
504 struct IDiscordApplicationManager
505 {
506     private
507     {
508         void function(IDiscordApplicationManager*, void*, void function(void*, DiscordResult)) validate_or_exitFunc;
509         void function(IDiscordApplicationManager*, DiscordLocale*) get_current_localeFunc;
510         void function(IDiscordApplicationManager*, DiscordBranch*) get_current_branchFunc;
511         void function(IDiscordApplicationManager*, void*, void function(void*, DiscordResult, DiscordOAuth2Token*)) get_oauth2_tokenFunc;
512         void function(IDiscordApplicationManager*, void*, void function(void*, DiscordResult, const(char)*)) get_ticketFunc;
513     }
514 
515     void validateOrExit(void* callbackData, void function(void*, DiscordResult) callback)
516     {
517         validate_or_exitFunc(&this, callbackData, callback);
518     }
519 
520     void getCurrentLocale(DiscordLocale* locale)
521     {
522         get_current_localeFunc(&this, locale);
523     }
524 
525     void getCurrentBranch(DiscordBranch* branch)
526     {
527         get_current_branchFunc(&this, branch);
528     }
529 
530     void getOauth2Token(void* callbackData, void function(void*, DiscordResult, DiscordOAuth2Token*) callback)
531     {
532         get_oauth2_tokenFunc(&this, callbackData, callback);
533     }
534 
535     void getTicket(void* callbackData, void function(void*, DiscordResult, const(char)*) callback)
536     {
537         get_ticketFunc(&this, callbackData, callback);
538     }
539 }
540 
541 struct IDiscordUserEvents
542 {
543     void function(void*) onCurrentUserUpdate;
544 }
545 
546 struct IDiscordUserManager
547 {
548     private
549     {
550         DiscordResult function(IDiscordUserManager*, DiscordUser*) get_current_userFunc;
551         void function(IDiscordUserManager*, DiscordUserId, void*, void function(void*, DiscordResult, DiscordUser*)) get_userFunc;
552         DiscordResult function(IDiscordUserManager*, DiscordPremiumType*) get_current_user_premium_typeFunc;
553         DiscordResult function(IDiscordUserManager*, DiscordUserFlag, bool*) current_user_has_flagFunc;
554     }
555 
556     DiscordResult getCurrentUser(DiscordUser* user)
557     {
558         return get_current_userFunc(&this, user);
559     }
560 
561     void getUser(DiscordUserId userId, void* callbackData, void function(void*, DiscordResult, DiscordUser*) callback)
562     {
563         get_userFunc(&this, userId, callbackData, callback);
564     }
565 
566     DiscordResult getCurrentUserPremiumType(DiscordPremiumType* premiumType)
567     {
568         return get_current_user_premium_typeFunc(&this, premiumType);
569     }
570 
571     DiscordResult currentUserHasFlag(DiscordUserFlag flag, bool* hasFlag)
572     {
573         return current_user_has_flagFunc(&this, flag, hasFlag);
574     }
575 }
576 
577 alias IDiscordImageEvents = void*;
578 
579 struct IDiscordImageManager
580 {
581     private
582     {
583         void function(IDiscordImageManager*, DiscordImageHandle, bool, void*, void function(void*, DiscordResult, DiscordImageHandle)) fetchFunc;
584         DiscordResult function(IDiscordImageManager*, DiscordImageHandle, DiscordImageDimensions*) get_dimensionsFunc;
585         DiscordResult function(IDiscordImageManager*, DiscordImageHandle, ubyte*, uint) get_dataFunc;
586     }
587 
588     void fetch(DiscordImageHandle handle, bool refresh, void* callbackData, void function(void*, DiscordResult, DiscordImageHandle) callback)
589     {
590         fetchFunc(&this, handle, refresh, callbackData, callback);
591     }
592 
593     DiscordResult getDimensions(DiscordImageHandle handle, DiscordImageDimensions* dimensions)
594     {
595         return get_dimensionsFunc(&this, handle, dimensions);
596     }
597 
598     DiscordResult getData(DiscordImageHandle handle, ubyte* data, uint dataLength)
599     {
600         return get_dataFunc(&this, handle, data, dataLength);
601     }
602 }
603 
604 struct IDiscordActivityEvents
605 {
606     void function(void*, const(char)*) onActivityJoin;
607     void function(void*, const(char)*) onActivitySpectate;
608     void function(void*, DiscordUser*) onActivityJoinRequest;
609     void function(void*, DiscordActivityActionType, DiscordUser*, DiscordActivity*) onActivityInvite;
610 }
611 
612 struct IDiscordActivityManager
613 {
614     private
615     {
616         DiscordResult function(IDiscordActivityManager*, const(char)*) register_commandFunc;
617         DiscordResult function(IDiscordActivityManager*, uint) register_steamFunc;
618         void function(IDiscordActivityManager*, DiscordActivity*, void*, void function(void*, DiscordResult)) update_activityFunc;
619         void function(IDiscordActivityManager*, void*, void function(void*, DiscordResult)) clear_activityFunc;
620         void function(IDiscordActivityManager*, DiscordUserId, DiscordActivityJoinRequestReply, void*, void function(void*, DiscordResult)) send_request_replyFunc;
621         void function(IDiscordActivityManager*, DiscordUserId, DiscordActivityActionType, const(char)*, void*, void function(void*, DiscordResult)) send_inviteFunc;
622         void function(IDiscordActivityManager*, DiscordUserId, void*, void function(void*, DiscordResult)) accept_inviteFunc;
623     }
624 
625     DiscordResult registerCommand(const(char)* command)
626     {
627         return register_commandFunc(&this, command);
628     }
629 
630     DiscordResult registerSteam(uint steamId)
631     {
632         return register_steamFunc(&this, steamId);
633     }
634 
635     extern (D) void updateActivity(DiscordActivity* activity, void function(DiscordResult) callback)
636     {
637         update_activityFunc(&this, activity, cast(void*) callback, &callbackWrapper);
638     }
639 
640     extern (D) void clearActivity(void function(DiscordResult) callback)
641     {
642         clear_activityFunc(&this, cast(void*) callback, &callbackWrapper);
643     }
644 
645     extern (D) void sendRequestReply(DiscordUserId userId, DiscordActivityJoinRequestReply reply, void function(
646             DiscordResult) callback)
647     {
648         send_request_replyFunc(&this, userId, reply, cast(void*) callback, &callbackWrapper);
649     }
650 
651     extern (D) void sendInvite(DiscordUserId userId, DiscordActivityActionType actionType, const(
652             char)* content, void function(DiscordResult) callback)
653     {
654         send_inviteFunc(&this, userId, actionType, content, cast(void*) callback, &callbackWrapper);
655     }
656 
657     extern (D) void acceptInvite(DiscordUserId userId, void function(DiscordResult) callback)
658     {
659         accept_inviteFunc(&this, userId, cast(void*) callback, &callbackWrapper);
660     }
661 
662     private static void callbackWrapper(void* data, DiscordResult result)
663     {
664         auto func = cast(void function(DiscordResult) nothrow) data;
665         func(result);
666     }
667 }
668 
669 struct IDiscordRelationshipEvents
670 {
671     void function(void*) onRefresh;
672     void function(void*, DiscordRelationship*) onRelationshipUpdate;
673 }
674 
675 struct IDiscordRelationshipManager
676 {
677     private
678     {
679         void function(IDiscordRelationshipManager*, void*, bool function(void*, DiscordRelationship*)) filterFunc;
680         DiscordResult function(IDiscordRelationshipManager*, int*) countFunc;
681         DiscordResult function(IDiscordRelationshipManager*, DiscordUserId, DiscordRelationship*) getFunc;
682         DiscordResult function(IDiscordRelationshipManager*, uint, DiscordRelationship*) get_atFunc;
683     }
684 
685     extern (D) void filter(bool function(DiscordRelationship*) callback)
686     {
687         filterFunc(&this, null, &callbackWrapper);
688     }
689 
690     DiscordResult count(int* count)
691     {
692         return countFunc(&this, count);
693     }
694 
695     DiscordResult get(DiscordUserId userId, DiscordRelationship* relationship)
696     {
697         return getFunc(&this, userId, relationship);
698     }
699 
700     DiscordResult getAt(uint index, DiscordRelationship* relationship)
701     {
702         return get_atFunc(&this, index, relationship);
703     }
704 
705     private static bool callbackWrapper(void* data, DiscordRelationship* relationship)
706     {
707         auto func = cast(bool function(DiscordRelationship*) nothrow) data;
708         return func(relationship);
709     }
710 }
711 
712 struct IDiscordLobbyEvents
713 {
714     void function(void*, long) onLobbyUpdate;
715     void function(void*, long, uint) onLobbyDelete;
716     void function(void*, long, long) onMemberConnect;
717     void function(void*, long, long) onMemberUpdate;
718     void function(void*, long, long) onMemberDisconnect;
719     void function(void*, long, long, ubyte*, uint) onLobbyMessage;
720     void function(void*, long, long, bool) onSpeaking;
721     void function(void*, long, long, ubyte, ubyte*, uint) onNetworkMessage;
722 }
723 
724 struct IDiscordLobbyManager
725 {
726     private
727     {
728         DiscordResult function(IDiscordLobbyManager*, IDiscordLobbyTransaction**) get_lobby_create_transactionFunc;
729         DiscordResult function(IDiscordLobbyManager*, DiscordLobbyId, IDiscordLobbyTransaction**) get_lobby_update_transactionFunc;
730         DiscordResult function(IDiscordLobbyManager*, DiscordLobbyId, DiscordUserId, IDiscordLobbyMemberTransaction**) get_member_update_transactionFunc;
731         void function(IDiscordLobbyManager*, IDiscordLobbyTransaction*, void*, void function(void*, DiscordResult, DiscordLobby*)) create_lobbyFunc;
732         void function(IDiscordLobbyManager*, DiscordLobbyId, IDiscordLobbyTransaction*, void*, void function(void*, DiscordResult)) update_lobbyFunc;
733         void function(IDiscordLobbyManager*, DiscordLobbyId, void*, void function(void*, DiscordResult)) delete_lobbyFunc;
734         void function(IDiscordLobbyManager*, DiscordLobbyId, DiscordLobbySecret, void*, void function(void*, DiscordResult, DiscordLobby*)) connect_lobbyFunc;
735         void function(IDiscordLobbyManager*, DiscordLobbySecret, void*, void function(void*, DiscordResult, DiscordLobby*)) connect_lobby_with_activity_secretFunc;
736         void function(IDiscordLobbyManager*, DiscordLobbyId, void*, void function(void*, DiscordResult)) disconnect_lobbyFunc;
737         DiscordResult function(IDiscordLobbyManager*, DiscordLobbyId, DiscordLobby*) get_lobbyFunc;
738         DiscordResult function(IDiscordLobbyManager*, DiscordLobbyId, DiscordLobbySecret*) get_lobby_activity_secretFunc;
739         DiscordResult function(IDiscordLobbyManager*, DiscordLobbyId, DiscordMetadataKey, DiscordMetadataValue*) get_lobby_metadata_valueFunc;
740         DiscordResult function(IDiscordLobbyManager*, DiscordLobbyId, int, DiscordMetadataKey*) get_lobby_metadata_keyFunc;
741         DiscordResult function(IDiscordLobbyManager*, DiscordLobbyId, int*) lobby_metadata_countFunc;
742         DiscordResult function(IDiscordLobbyManager*, DiscordLobbyId, int*) member_countFunc;
743         DiscordResult function(IDiscordLobbyManager*, DiscordLobbyId, int, DiscordUserId*) get_member_user_idFunc;
744         DiscordResult function(IDiscordLobbyManager*, DiscordLobbyId, DiscordUserId, DiscordUser*) get_member_userFunc;
745         DiscordResult function(IDiscordLobbyManager*, DiscordLobbyId, DiscordUserId, DiscordMetadataKey, DiscordMetadataValue*) get_member_metadata_valueFunc;
746         DiscordResult function(IDiscordLobbyManager*, DiscordLobbyId, DiscordUserId, int, DiscordMetadataKey*) get_member_metadata_keyFunc;
747         DiscordResult function(IDiscordLobbyManager*, DiscordLobbyId, DiscordUserId, int*) member_metadata_countFunc;
748         void function(IDiscordLobbyManager*, DiscordLobbyId, DiscordUserId, IDiscordLobbyMemberTransaction*, void*, void function(void*, DiscordResult)) update_memberFunc;
749         void function(IDiscordLobbyManager*, DiscordLobbyId, ubyte*, uint, void*, void function(void*, DiscordResult)) send_lobby_messageFunc;
750         DiscordResult function(IDiscordLobbyManager*, IDiscordLobbySearchQuery**) get_search_queryFunc;
751         void function(IDiscordLobbyManager*, IDiscordLobbySearchQuery*, void*, void function(void*, DiscordResult)) searchFunc;
752         void function(IDiscordLobbyManager*, int*) lobby_countFunc;
753         DiscordResult function(IDiscordLobbyManager*, int, DiscordLobbyId*) get_lobby_idFunc;
754         void function(IDiscordLobbyManager*, DiscordLobbyId, void*, void function(void*, DiscordResult)) connect_voiceFunc;
755         void function(IDiscordLobbyManager*, DiscordLobbyId, void*, void function(void*, DiscordResult)) disconnect_voiceFunc;
756         DiscordResult function(IDiscordLobbyManager*, DiscordLobbyId) connect_networkFunc;
757         DiscordResult function(IDiscordLobbyManager*, DiscordLobbyId) disconnect_networkFunc;
758         DiscordResult function(IDiscordLobbyManager*) flush_networkFunc;
759         DiscordResult function(IDiscordLobbyManager*, DiscordLobbyId, ubyte, bool) open_network_channelFunc;
760         DiscordResult function(IDiscordLobbyManager*, DiscordLobbyId, DiscordUserId, ubyte, ubyte*, uint) send_network_messageFunc;
761     }
762 
763     DiscordResult getLobbyCreateTransaction(IDiscordLobbyTransaction** transaction)
764     {
765         return get_lobby_create_transactionFunc(&this, transaction);
766     }
767 
768     DiscordResult getLobbyUpdateTransaction(DiscordLobbyId lobbyId, IDiscordLobbyTransaction** transaction)
769     {
770         return get_lobby_update_transactionFunc(&this, lobbyId, transaction);
771     }
772 
773     DiscordResult getMemberUpdateTransaction(DiscordLobbyId lobbyId, DiscordUserId userId, IDiscordLobbyMemberTransaction** transaction)
774     {
775         return get_member_update_transactionFunc(&this, lobbyId, userId, transaction);
776     }
777 
778     void createLobby(IDiscordLobbyTransaction* transaction, void function(DiscordResult, DiscordLobby*) callback)
779     {
780         create_lobbyFunc(&this, transaction, cast(void*) callback, &lobbyCallbackWrapper);
781     }
782 
783     void updateLobby(DiscordLobbyId lobbyId, IDiscordLobbyTransaction* transaction, void function(DiscordResult) callback)
784     {
785         update_lobbyFunc(&this, lobbyId, transaction, cast(void*) callback, &resultCallbackWrapper);
786     }
787 
788     void deleteLobby(DiscordLobbyId lobbyId, void function(DiscordResult) callback)
789     {
790         delete_lobbyFunc(&this, lobbyId, cast(void*) callback, &resultCallbackWrapper);
791     }
792 
793     void connectLobby(DiscordLobbyId lobbyId, DiscordLobbySecret secret, void function(DiscordResult, DiscordLobby*) callback)
794     {
795         connect_lobbyFunc(&this, lobbyId, secret, cast(void*) callback, &lobbyCallbackWrapper);
796     }
797 
798     void connectLobbyWithActivitySecret(DiscordLobbySecret activitySecret, void function(DiscordResult, DiscordLobby*) callback)
799     {
800         connect_lobby_with_activity_secretFunc(&this, activitySecret, cast(void*) callback, &lobbyCallbackWrapper);
801     }
802 
803     void disconnectLobby(DiscordLobbyId lobbyId, void function(DiscordResult) callback)
804     {
805         disconnect_lobbyFunc(&this, lobbyId, cast(void*) callback, &resultCallbackWrapper);
806     }
807 
808     DiscordResult getLobby(DiscordLobbyId lobbyId, DiscordLobby* lobby)
809     {
810         return get_lobbyFunc(&this, lobbyId, lobby);
811     }
812 
813     DiscordResult getLobbyActivitySecret(DiscordLobbyId lobbyId, DiscordLobbySecret* secret)
814     {
815         return get_lobby_activity_secretFunc(&this, lobbyId, secret);
816     }
817 
818     DiscordResult getLobbyMetadataValue(DiscordLobbyId lobbyId, DiscordMetadataKey key, DiscordMetadataValue* value)
819     {
820         return get_lobby_metadata_valueFunc(&this, lobbyId, key, value);
821     }
822 
823     DiscordResult getLobbyMetadataKey(DiscordLobbyId lobbyId, int index, DiscordMetadataKey* key)
824     {
825         return get_lobby_metadata_keyFunc(&this, lobbyId, index, key);
826     }
827 
828     DiscordResult lobbyMetadataCount(DiscordLobbyId lobbyId, int* count)
829     {
830         return lobby_metadata_countFunc(&this, lobbyId, count);
831     }
832 
833     DiscordResult memberCount(DiscordLobbyId lobbyId, int* count)
834     {
835         return member_countFunc(&this, lobbyId, count);
836     }
837 
838     DiscordResult getMemberUserId(DiscordLobbyId lobbyId, int index, DiscordUserId* userId)
839     {
840         return get_member_user_idFunc(&this, lobbyId, index, userId);
841     }
842 
843     DiscordResult getMemberUser(DiscordLobbyId lobbyId, DiscordUserId userId, DiscordUser* user)
844     {
845         return get_member_userFunc(&this, lobbyId, userId, user);
846     }
847 
848     DiscordResult getMemberMetadataValue(DiscordLobbyId lobbyId, DiscordUserId userId, DiscordMetadataKey key, DiscordMetadataValue* value)
849     {
850         return get_member_metadata_valueFunc(&this, lobbyId, userId, key, value);
851     }
852 
853     DiscordResult getMemberMetadataKey(DiscordLobbyId lobbyId, DiscordUserId userId, int index, DiscordMetadataKey* key)
854     {
855         return get_member_metadata_keyFunc(&this, lobbyId, userId, index, key);
856     }
857 
858     DiscordResult memberMetadataCount(DiscordLobbyId lobbyId, DiscordUserId userId, int* count)
859     {
860         return member_metadata_countFunc(&this, lobbyId, userId, count);
861     }
862 
863     void updateMember(DiscordLobbyId lobbyId, DiscordUserId userId, IDiscordLobbyMemberTransaction* transaction, void function(DiscordResult) callback)
864     {
865         update_memberFunc(&this, lobbyId, userId, transaction, cast(void*) callback, &resultCallbackWrapper);
866     }
867 
868     void sendLobbyMessage(DiscordLobbyId lobbyId, ubyte* data, uint dataLength, void function(DiscordResult) callback)
869     {
870         send_lobby_messageFunc(&this, lobbyId, data, dataLength, cast(void*) callback, &resultCallbackWrapper);
871     }
872 
873     DiscordResult getSearchQuery(IDiscordLobbySearchQuery** query)
874     {
875         return get_search_queryFunc(&this, query);
876     }
877 
878     void search(IDiscordLobbySearchQuery* query, void function(DiscordResult) callback)
879     {
880         searchFunc(&this, query, cast(void*) callback, &resultCallbackWrapper);
881     }
882 
883     void lobbyCount(int* count)
884     {
885         lobby_countFunc(&this, count);
886     }
887 
888     DiscordResult getLobbyId(int index, DiscordLobbyId* lobbyId)
889     {
890         return get_lobby_idFunc(&this, index, lobbyId);
891     }
892 
893     void connectVoice(DiscordLobbyId lobbyId, void function(DiscordResult) callback)
894     {
895         connect_voiceFunc(&this, lobbyId, cast(void*) callback, &resultCallbackWrapper);
896     }
897 
898     void disconnectVoice(DiscordLobbyId lobbyId, void function(DiscordResult) callback)
899     {
900         disconnect_voiceFunc(&this, lobbyId, cast(void*) callback, &resultCallbackWrapper);
901     }
902 
903     DiscordResult connectNetwork(DiscordLobbyId lobbyId)
904     {
905         return connect_networkFunc(&this, lobbyId);
906     }
907 
908     DiscordResult disconnectNetwork(DiscordLobbyId lobbyId)
909     {
910         return disconnect_networkFunc(&this, lobbyId);
911     }
912 
913     DiscordResult flushNetwork()
914     {
915         return flush_networkFunc(&this);
916     }
917 
918     DiscordResult openNetworkChannel(DiscordLobbyId lobbyId, ubyte channelId, bool reliable)
919     {
920         return open_network_channelFunc(&this, lobbyId, channelId, reliable);
921     }
922 
923     DiscordResult sendNetworkMessage(DiscordLobbyId lobbyId, DiscordUserId userId, ubyte channelId, ubyte* data, uint dataLength)
924     {
925         return send_network_messageFunc(&this, lobbyId, userId, channelId, data, dataLength);
926     }
927 
928     private static void lobbyCallbackWrapper(void* data, DiscordResult result, DiscordLobby* lobby)
929     {
930         auto func = cast(void function(DiscordResult, DiscordLobby*) nothrow) data;
931         func(result, lobby);
932     }
933 
934     private static void resultCallbackWrapper(void* data, DiscordResult result)
935     {
936         auto func = cast(void function(DiscordResult) nothrow) data;
937         func(result);
938     }
939 }
940 
941 struct IDiscordNetworkEvents
942 {
943     void function(void*, DiscordNetworkPeerId, DiscordNetworkChannelId, ubyte*, uint) onMessage;
944     void function(void*, const(char)*) onRouteUpdate;
945 }
946 
947 struct IDiscordNetworkManager
948 {
949     private
950     {
951         void function(IDiscordNetworkManager*, DiscordNetworkPeerId*) get_peer_idFunc;
952         DiscordResult function(IDiscordNetworkManager*) flushFunc;
953         DiscordResult function(IDiscordNetworkManager*, DiscordNetworkPeerId, const(char)*) open_peerFunc;
954         DiscordResult function(IDiscordNetworkManager*, DiscordNetworkPeerId, const(char)*) update_peerFunc;
955         DiscordResult function(IDiscordNetworkManager*, DiscordNetworkPeerId) close_peerFunc;
956         DiscordResult function(IDiscordNetworkManager*, DiscordNetworkPeerId, DiscordNetworkChannelId, bool) open_channelFunc;
957         DiscordResult function(IDiscordNetworkManager*, DiscordNetworkPeerId, DiscordNetworkChannelId) close_channelFunc;
958         DiscordResult function(IDiscordNetworkManager*, DiscordNetworkPeerId, DiscordNetworkChannelId, ubyte*, uint) send_messageFunc;
959     }
960 
961     /**
962     * Get the local peer ID for this process.
963     */
964     void getPeerId(DiscordNetworkPeerId* peerId)
965     {
966         get_peer_idFunc(&this, peerId);
967     }
968 
969     /**
970     * Send pending network messages.
971     */
972     DiscordResult flush()
973     {
974         return flushFunc(&this);
975     }
976 
977     /**
978     * Open a connection to a remote peer.
979     */
980     DiscordResult openPeer(DiscordNetworkPeerId peerId, const(char)* routeData)
981     {
982         return open_peerFunc(&this, peerId, routeData);
983     }
984 
985     /**
986     * Update the route data for a connected peer.
987     */
988     DiscordResult updatePeer(DiscordNetworkPeerId peerId, const(char)* routeData)
989     {
990         return update_peerFunc(&this, peerId, routeData);
991     }
992 
993     /**
994     * Close the connection to a remote peer.
995     */
996     DiscordResult closePeer(DiscordNetworkPeerId peerId)
997     {
998         return close_peerFunc(&this, peerId);
999     }
1000 
1001     /**
1002     * Open a message channel to a connected peer.
1003     */
1004     DiscordResult openChannel(DiscordNetworkPeerId peerId, DiscordNetworkChannelId channelId, bool reliable)
1005     {
1006         return open_channelFunc(&this, peerId, channelId, reliable);
1007     }
1008 
1009     /**
1010     * Close a message channel to a connected peer.
1011     */
1012     DiscordResult closeChannel(DiscordNetworkPeerId peerId, DiscordNetworkChannelId channelId)
1013     {
1014         return close_channelFunc(&this, peerId, channelId);
1015     }
1016 
1017     /**
1018     * Send a message to a connected peer over an opened message channel.
1019     */
1020     DiscordResult sendMessage(DiscordNetworkPeerId peerId, DiscordNetworkChannelId channelId, ubyte* data, uint dataLength)
1021     {
1022         return send_messageFunc(&this, peerId, channelId, data, dataLength);
1023     }
1024 }
1025 
1026 struct IDiscordOverlayEvents
1027 {
1028     void function(void*, bool) onToggle;
1029 }
1030 
1031 struct IDiscordOverlayManager
1032 {
1033     private
1034     {
1035         void function(IDiscordOverlayManager*, bool*) is_enabledFunc;
1036         void function(IDiscordOverlayManager*, bool*) is_lockedFunc;
1037         void function(IDiscordOverlayManager*, bool, void*, void function(void*, DiscordResult)) set_lockedFunc;
1038         void function(IDiscordOverlayManager*, DiscordActivityActionType, void*, void function(void*, DiscordResult)) open_activity_inviteFunc;
1039         void function(IDiscordOverlayManager*, const(char)*, void*, void function(void*, DiscordResult)) open_guild_inviteFunc;
1040         void function(IDiscordOverlayManager*, void*, void function(void*, DiscordResult)) open_voice_settingsFunc;
1041         DiscordResult function(IDiscordOverlayManager*, void*, bool) init_drawing_dxgiFunc;
1042         void function(IDiscordOverlayManager*) on_presentFunc;
1043         void function(IDiscordOverlayManager*, void*) forward_messageFunc;
1044         void function(IDiscordOverlayManager*, bool, const(char)*, DiscordKeyVariant) key_eventFunc;
1045         void function(IDiscordOverlayManager*, const(char)*) char_eventFunc;
1046         void function(IDiscordOverlayManager*, ubyte, int, DiscordMouseButton, int, int) mouse_button_eventFunc;
1047         void function(IDiscordOverlayManager*, int, int) mouse_motion_eventFunc;
1048         void function(IDiscordOverlayManager*, const(char)*) ime_commit_textFunc;
1049         void function(IDiscordOverlayManager*, const(char)*, DiscordImeUnderline*, uint, int, int) ime_set_compositionFunc;
1050         void function(IDiscordOverlayManager*) ime_cancel_compositionFunc;
1051         void function(IDiscordOverlayManager*, void*, void function(void*, int, int, DiscordRect*, uint)) set_ime_composition_range_callbackFunc;
1052         void function(IDiscordOverlayManager*, void*, void function(void*, DiscordRect, DiscordRect, bool)) set_ime_selection_bounds_callbackFunc;
1053         bool function(IDiscordOverlayManager*, int, int) is_point_inside_click_zoneFunc;
1054     }
1055 
1056     void isEnabled(bool* enabled)
1057     {
1058         is_enabledFunc(&this, enabled);
1059     }
1060 
1061     void isLocked(bool* locked)
1062     {
1063         is_lockedFunc(&this, locked);
1064     }
1065 
1066     void setLocked(bool locked, void function(DiscordResult) callback)
1067     {
1068         set_lockedFunc(&this, locked, cast(void*) callback, &resultCallbackWrapper);
1069     }
1070 
1071     void openActivityInvite(DiscordActivityActionType type, void function(DiscordResult) callback)
1072     {
1073         open_activity_inviteFunc(&this, type, cast(void*) callback, &resultCallbackWrapper);
1074     }
1075 
1076     void openGuildInvite(const(char)* code, void function(DiscordResult) callback)
1077     {
1078         open_guild_inviteFunc(&this, code, cast(void*) callback, &resultCallbackWrapper);
1079     }
1080 
1081     void openVoiceSettings(void function(DiscordResult) callback)
1082     {
1083         open_voice_settingsFunc(&this, cast(void*) callback, &resultCallbackWrapper);
1084     }
1085 
1086     DiscordResult initDrawingDxgi(void* swapChain, bool useMessageForwarding)
1087     {
1088         return init_drawing_dxgiFunc(&this, swapChain, useMessageForwarding);
1089     }
1090 
1091     void onPresent()
1092     {
1093         on_presentFunc(&this);
1094     }
1095 
1096     void forwardMessage(void* message)
1097     {
1098         forward_messageFunc(&this, message);
1099     }
1100 
1101     void keyEvent(bool down, const(char)* keyCode, DiscordKeyVariant variant)
1102     {
1103         key_eventFunc(&this, down, keyCode, variant);
1104     }
1105 
1106     void charEvent(const(char)* character)
1107     {
1108         char_eventFunc(&this, character);
1109     }
1110 
1111     void mouseButtonEvent(ubyte down, int clickCount, DiscordMouseButton button, int x, int y)
1112     {
1113         mouse_button_eventFunc(&this, down, clickCount, button, x, y);
1114     }
1115 
1116     void mouseMotionEvent(int x, int y)
1117     {
1118         mouse_motion_eventFunc(&this, x, y);
1119     }
1120 
1121     void imeCommitText(const(char)* text)
1122     {
1123         ime_commit_textFunc(&this, text);
1124     }
1125 
1126     void imeSetComposition(const(char)* text, DiscordImeUnderline* underlines, uint underlineLength, int from, int to)
1127     {
1128         ime_set_compositionFunc(&this, text, underlines, underlineLength, from, to);
1129     }
1130 
1131     void imeCancelComposition()
1132     {
1133         ime_cancel_compositionFunc(&this);
1134     }
1135 
1136     void setImeCompositionRangeCallback(void function(int, int, DiscordRect*, uint) callback)
1137     {
1138         set_ime_composition_range_callbackFunc(&this, cast(void*) callback, &imeCompositionCallbackWrapper);
1139     }
1140 
1141     void setImeSelectionBoundsCallback(void function(DiscordRect, DiscordRect, bool) callback)
1142     {
1143         set_ime_selection_bounds_callbackFunc(&this, cast(void*) callback, &imeSelectionBoundsCallbackWrapper);
1144     }
1145 
1146     bool isPointInsideClickZone(int x, int y)
1147     {
1148         return is_point_inside_click_zoneFunc(&this, x, y);
1149     }
1150 
1151     private static void resultCallbackWrapper(void* data, DiscordResult result)
1152     {
1153         auto func = cast(void function(DiscordResult) nothrow) data;
1154         func(result);
1155     }
1156 
1157     private static void imeCompositionCallbackWrapper(void* data, int from, int to, DiscordRect* bounds, uint boundsLength)
1158     {
1159         auto func = cast(void function(int, int, DiscordRect*, uint) nothrow) data;
1160         func(from, to, bounds, boundsLength);
1161     }
1162 
1163     private static void imeSelectionBoundsCallbackWrapper(void* data, DiscordRect anchor, DiscordRect focus, bool isAnchorFirst)
1164     {
1165         auto func = cast(void function(DiscordRect, DiscordRect, bool) nothrow) data;
1166         func(anchor, focus, isAnchorFirst);
1167     }
1168 }
1169 
1170 alias IDiscordStorageEvents = void*;
1171 
1172 struct IDiscordStorageManager
1173 {
1174     private
1175     {
1176         DiscordResult function(IDiscordStorageManager*, const(char)*, ubyte*, uint, uint*) readFunc;
1177         void function(IDiscordStorageManager*, const(char)*, void*, void function(void*, DiscordResult, ubyte*, uint)) read_asyncFunc;
1178         void function(IDiscordStorageManager*, const(char)*, ulong, ulong, void*, void function(void*, DiscordResult, ubyte*, uint)) read_async_partialFunc;
1179         DiscordResult function(IDiscordStorageManager*, const(char)*, ubyte*, uint) writeFunc;
1180         void function(IDiscordStorageManager*, const(char)*, ubyte*, uint, void*, void function(void*, DiscordResult)) write_asyncFunc;
1181         DiscordResult function(IDiscordStorageManager*, const(char)*) delete_Func;
1182         DiscordResult function(IDiscordStorageManager*, const(char)*, bool*) existsFunc;
1183         void function(IDiscordStorageManager*, int*) countFunc;
1184         DiscordResult function(IDiscordStorageManager*, const(char)*, DiscordFileStat*) statFunc;
1185         DiscordResult function(IDiscordStorageManager*, int, DiscordFileStat*) stat_atFunc;
1186         DiscordResult function(IDiscordStorageManager*, DiscordPath*) get_pathFunc;
1187     }
1188 
1189     DiscordResult read(const(char)* name, ubyte* data, uint dataLength, uint* read)
1190     {
1191         return readFunc(&this, name, data, dataLength, read);
1192     }
1193 
1194     void readAsync(const(char)* name, void* callbackData, void function(void*, DiscordResult, ubyte*, uint) callback)
1195     {
1196         read_asyncFunc(&this, name, callbackData, callback);
1197     }
1198 
1199     void readAsyncPartial(const(char)* name, ulong offset, ulong length, void* callbackData, void function(void*, DiscordResult, ubyte*, uint) callback)
1200     {
1201         read_async_partialFunc(&this, name, offset, length, callbackData, callback);
1202     }
1203 
1204     DiscordResult write(const(char)* name, ubyte* data, uint dataLength)
1205     {
1206         return writeFunc(&this, name, data, dataLength);
1207     }
1208 
1209     void writeAsync(const(char)* name, ubyte* data, uint dataLength, void* callbackData, void function(void*, DiscordResult) callback)
1210     {
1211         write_asyncFunc(&this, name, data, dataLength, callbackData, callback);
1212     }
1213 
1214     DiscordResult delete_(const(char)* name)
1215     {
1216         return delete_Func(&this, name);
1217     }
1218 
1219     DiscordResult exists(const(char)* name, bool* exists)
1220     {
1221         return existsFunc(&this, name, exists);
1222     }
1223 
1224     void count(int* count)
1225     {
1226         countFunc(&this, count);
1227     }
1228 
1229     DiscordResult stat(const(char)* name, DiscordFileStat* stat)
1230     {
1231         return statFunc(&this, name, stat);
1232     }
1233 
1234     DiscordResult statAt(int index, DiscordFileStat* stat)
1235     {
1236         return stat_atFunc(&this, index, stat);
1237     }
1238 
1239     DiscordResult getPath(DiscordPath* path)
1240     {
1241         return get_pathFunc(&this, path);
1242     }
1243 }
1244 
1245 struct IDiscordStoreEvents
1246 {
1247     void function(void*, DiscordEntitlement*) onEntitlementCreate;
1248     void function(void*, DiscordEntitlement*) onEntitlementDelete;
1249 }
1250 
1251 struct IDiscordStoreManager
1252 {
1253     private
1254     {
1255         void function(IDiscordStoreManager*, void*, void function(void*, DiscordResult)) fetch_skusFunc;
1256         void function(IDiscordStoreManager*, int*) count_skusFunc;
1257         DiscordResult function(IDiscordStoreManager*, DiscordSnowflake, DiscordSku*) get_skuFunc;
1258         DiscordResult function(IDiscordStoreManager*, int, DiscordSku*) get_sku_atFunc;
1259         void function(IDiscordStoreManager*, void*, void function(void*, DiscordResult)) fetch_entitlementsFunc;
1260         void function(IDiscordStoreManager*, int*) count_entitlementsFunc;
1261         DiscordResult function(IDiscordStoreManager*, DiscordSnowflake, DiscordEntitlement*) get_entitlementFunc;
1262         DiscordResult function(IDiscordStoreManager*, int, DiscordEntitlement*) get_entitlement_atFunc;
1263         DiscordResult function(IDiscordStoreManager*, DiscordSnowflake, bool*) has_sku_entitlementFunc;
1264         void function(IDiscordStoreManager*, DiscordSnowflake, void*, void function(void*, DiscordResult)) start_purchaseFunc;
1265     }
1266 
1267     void fetchSkus(void function(DiscordResult) callback)
1268     {
1269         fetch_skusFunc(&this, cast(void*) callback, &resultCallbackWrapper);
1270     }
1271 
1272     void countSkus(int* count)
1273     {
1274         count_skusFunc(&this, count);
1275     }
1276 
1277     DiscordResult getSku(DiscordSnowflake skuId, DiscordSku* sku)
1278     {
1279         return get_skuFunc(&this, skuId, sku);
1280     }
1281 
1282     DiscordResult getSkuAt(int index, DiscordSku* sku)
1283     {
1284         return get_sku_atFunc(&this, index, sku);
1285     }
1286 
1287     void fetchEntitlements(void function(DiscordResult) callback)
1288     {
1289         fetch_entitlementsFunc(&this, cast(void*) callback, &resultCallbackWrapper);
1290     }
1291 
1292     void countEntitlements(int* count)
1293     {
1294         count_entitlementsFunc(&this, count);
1295     }
1296 
1297     DiscordResult getEntitlement(DiscordSnowflake entitlementId, DiscordEntitlement* entitlement)
1298     {
1299         return get_entitlementFunc(&this, entitlementId, entitlement);
1300     }
1301 
1302     DiscordResult getEntitlementAt(int index, DiscordEntitlement* entitlement)
1303     {
1304         return get_entitlement_atFunc(&this, index, entitlement);
1305     }
1306 
1307     DiscordResult hasSkuEntitlement(DiscordSnowflake skuId, bool* hasEntitlement)
1308     {
1309         return has_sku_entitlementFunc(&this, skuId, hasEntitlement);
1310     }
1311 
1312     void startPurchase(DiscordSnowflake skuId, void function(DiscordResult) callback)
1313     {
1314         start_purchaseFunc(&this, skuId, cast(void*) callback, &resultCallbackWrapper);
1315     }
1316 
1317     private static void resultCallbackWrapper(void* data, DiscordResult result)
1318     {
1319         auto func = cast(void function(DiscordResult) nothrow) data;
1320         func(result);
1321     }
1322 }
1323 
1324 struct IDiscordVoiceEvents
1325 {
1326     void function(void*) onSettingsUpdate;
1327 }
1328 
1329 struct IDiscordVoiceManager
1330 {
1331     private
1332     {
1333         DiscordResult function(IDiscordVoiceManager*, DiscordInputMode*) get_input_modeFunc;
1334         void function(IDiscordVoiceManager*, DiscordInputMode, void*, void function(void*, DiscordResult)) set_input_modeFunc;
1335         DiscordResult function(IDiscordVoiceManager*, bool*) is_self_muteFunc;
1336         DiscordResult function(IDiscordVoiceManager*, bool) set_self_muteFunc;
1337         DiscordResult function(IDiscordVoiceManager*, bool*) is_self_deafFunc;
1338         DiscordResult function(IDiscordVoiceManager*, bool) set_self_deafFunc;
1339         DiscordResult function(IDiscordVoiceManager*, DiscordSnowflake, bool*) is_local_muteFunc;
1340         DiscordResult function(IDiscordVoiceManager*, DiscordSnowflake, bool) set_local_muteFunc;
1341         DiscordResult function(IDiscordVoiceManager*, DiscordSnowflake, ubyte*) get_local_volumeFunc;
1342         DiscordResult function(IDiscordVoiceManager*, DiscordSnowflake, ubyte) set_local_volumeFunc;
1343     }
1344 
1345     DiscordResult getInputMode(DiscordInputMode* inputMode)
1346     {
1347         return get_input_modeFunc(&this, inputMode);
1348     }
1349 
1350     void setInputMode(DiscordInputMode inputMode, void function(DiscordResult) callback)
1351     {
1352         set_input_modeFunc(&this, inputMode, cast(void*) callback, &resultCallbackWrapper);
1353     }
1354 
1355     DiscordResult isSelfMute(bool* mute)
1356     {
1357         return is_self_muteFunc(&this, mute);
1358     }
1359 
1360     DiscordResult setSelfMute(bool mute)
1361     {
1362         return set_self_muteFunc(&this, mute);
1363     }
1364 
1365     DiscordResult isSelfDeaf(bool* deaf)
1366     {
1367         return is_self_deafFunc(&this, deaf);
1368     }
1369 
1370     DiscordResult setSelfDeaf(bool deaf)
1371     {
1372         return set_self_deafFunc(&this, deaf);
1373     }
1374 
1375     DiscordResult isLocalMute(DiscordSnowflake userId, bool* mute)
1376     {
1377         return is_local_muteFunc(&this, userId, mute);
1378     }
1379 
1380     DiscordResult setLocalMute(DiscordSnowflake userId, bool mute)
1381     {
1382         return set_local_muteFunc(&this, userId, mute);
1383     }
1384 
1385     DiscordResult getLocalVolume(DiscordSnowflake userId, ubyte* volume)
1386     {
1387         return get_local_volumeFunc(&this, userId, volume);
1388     }
1389 
1390     DiscordResult setLocalVolume(DiscordSnowflake userId, ubyte volume)
1391     {
1392         return set_local_volumeFunc(&this, userId, volume);
1393     }
1394 
1395     private static void resultCallbackWrapper(void* data, DiscordResult result)
1396     {
1397         auto func = cast(void function(DiscordResult) nothrow) data;
1398         func(result);
1399     }
1400 }
1401 
1402 struct IDiscordAchievementEvents
1403 {
1404     void function(void*, DiscordUserAchievement*) onUserAchievementUpdate;
1405 }
1406 
1407 struct IDiscordAchievementManager
1408 {
1409     private
1410     {
1411         void function(IDiscordAchievementManager*, DiscordSnowflake, ubyte, void*, void function(void*, DiscordResult)) set_user_achievementFunc;
1412         void function(IDiscordAchievementManager*, void*, void function(void*, DiscordResult)) fetch_user_achievementsFunc;
1413         void function(IDiscordAchievementManager*, int*) count_user_achievementsFunc;
1414         DiscordResult function(IDiscordAchievementManager*, DiscordSnowflake, DiscordUserAchievement*) get_user_achievementFunc;
1415         DiscordResult function(IDiscordAchievementManager*, int, DiscordUserAchievement*) get_user_achievement_atFunc;
1416     }
1417 
1418     void setUserAchievement(DiscordSnowflake achievementId, ubyte percentComplete, void function(
1419             DiscordResult) callback)
1420     {
1421         set_user_achievementFunc(&this, achievementId, percentComplete, cast(void*) callback, &resultCallbackWrapper);
1422     }
1423 
1424     void fetchUserAchievements(void function(DiscordResult) callback)
1425     {
1426         fetch_user_achievementsFunc(&this, cast(void*) callback, &resultCallbackWrapper);
1427     }
1428 
1429     void countUserAchievements(int* count)
1430     {
1431         count_user_achievementsFunc(&this, count);
1432     }
1433 
1434     DiscordResult getUserAchievement(DiscordSnowflake achievementId, DiscordUserAchievement* userAchievement)
1435     {
1436         return get_user_achievementFunc(&this, achievementId, userAchievement);
1437     }
1438 
1439     DiscordResult getUserAchievementAt(int index, DiscordUserAchievement* userAchievement)
1440     {
1441         return get_user_achievement_atFunc(&this, index, userAchievement);
1442     }
1443 
1444     private static void resultCallbackWrapper(void* data, DiscordResult result)
1445     {
1446         auto func = cast(void function(DiscordResult) nothrow) data;
1447         func(result);
1448     }
1449 }
1450 
1451 alias IDiscordCoreEvents = void*;
1452 
1453 struct IDiscordCore
1454 {
1455     private
1456     {
1457         void function(IDiscordCore*) destroyFunc;
1458         DiscordResult function(IDiscordCore*) run_callbacksFunc;
1459         void function(IDiscordCore*, DiscordLogLevel, void*, void function(void*, DiscordLogLevel, const(char)*)) set_log_hookFunc;
1460         IDiscordApplicationManager* function(IDiscordCore*) get_application_managerFunc;
1461         IDiscordUserManager* function(IDiscordCore*) get_user_managerFunc;
1462         IDiscordImageManager* function(IDiscordCore*) get_image_managerFunc;
1463         IDiscordActivityManager* function(IDiscordCore*) get_activity_managerFunc;
1464         IDiscordRelationshipManager* function(IDiscordCore*) get_relationship_managerFunc;
1465         IDiscordLobbyManager* function(IDiscordCore*) get_lobby_managerFunc;
1466         IDiscordNetworkManager* function(IDiscordCore*) get_network_managerFunc;
1467         IDiscordOverlayManager* function(IDiscordCore*) get_overlay_managerFunc;
1468         IDiscordStorageManager* function(IDiscordCore*) get_storage_managerFunc;
1469         IDiscordStoreManager* function(IDiscordCore*) get_store_managerFunc;
1470         IDiscordVoiceManager* function(IDiscordCore*) get_voice_managerFunc;
1471         IDiscordAchievementManager* function(IDiscordCore*) get_achievement_managerFunc;
1472     }
1473 
1474     void destroy()
1475     {
1476         destroyFunc(&this);
1477     }
1478 
1479     DiscordResult runCallbacks()
1480     {
1481         return run_callbacksFunc(&this);
1482     }
1483 
1484     void setLogHook(DiscordLogLevel minLevel, void function(DiscordLogLevel, const(char)*) hook)
1485     {
1486         set_log_hookFunc(&this, minLevel, cast(void*) hook, &logHookCallbackWrapper);
1487     }
1488 
1489     IDiscordApplicationManager* getApplicationManager()
1490     {
1491         return get_application_managerFunc(&this);
1492     }
1493 
1494     IDiscordUserManager* getUserManager()
1495     {
1496         return get_user_managerFunc(&this);
1497     }
1498 
1499     IDiscordImageManager* getImageManager()
1500     {
1501         return get_image_managerFunc(&this);
1502     }
1503 
1504     IDiscordActivityManager* getActivityManager()
1505     {
1506         return get_activity_managerFunc(&this);
1507     }
1508 
1509     IDiscordRelationshipManager* getRelationshipManager()
1510     {
1511         return get_relationship_managerFunc(&this);
1512     }
1513 
1514     IDiscordLobbyManager* getLobbyManager()
1515     {
1516         return get_lobby_managerFunc(&this);
1517     }
1518 
1519     IDiscordNetworkManager* getNetworkManager()
1520     {
1521         return get_network_managerFunc(&this);
1522     }
1523 
1524     IDiscordOverlayManager* getOverlayManager()
1525     {
1526         return get_overlay_managerFunc(&this);
1527     }
1528 
1529     IDiscordStorageManager* getStorageManager()
1530     {
1531         return get_storage_managerFunc(&this);
1532     }
1533 
1534     IDiscordStoreManager* getStoreManager()
1535     {
1536         return get_store_managerFunc(&this);
1537     }
1538 
1539     IDiscordVoiceManager* getVoiceManager()
1540     {
1541         return get_voice_managerFunc(&this);
1542     }
1543 
1544     IDiscordAchievementManager* getAchievementManager()
1545     {
1546         return get_achievement_managerFunc(&this);
1547     }
1548 
1549     private static void logHookCallbackWrapper(void* data, DiscordLogLevel level, const(char)* message)
1550     {
1551         auto func = cast(void function(DiscordLogLevel, const(char)*) nothrow) data;
1552         func(level, message);
1553     }
1554 }
1555 
1556 struct DiscordCreateParams
1557 {
1558     DiscordClientId clientId;
1559     ulong flags;
1560     IDiscordCoreEvents* events;
1561     void* eventData;
1562     IDiscordApplicationEvents* applicationEvents;
1563     DiscordVersion applicationVersion;
1564     IDiscordUserEvents* userEvents;
1565     DiscordVersion userVersion;
1566     IDiscordImageEvents* imageEvents;
1567     DiscordVersion imageVersion;
1568     IDiscordActivityEvents* activityEvents;
1569     DiscordVersion activityVersion;
1570     IDiscordRelationshipEvents* relationshipEvents;
1571     DiscordVersion relationshipVersion;
1572     IDiscordLobbyEvents* lobbyEvents;
1573     DiscordVersion lobbyVersion;
1574     IDiscordNetworkEvents* networkEvents;
1575     DiscordVersion networkVersion;
1576     IDiscordOverlayEvents* overlayEvents;
1577     DiscordVersion overlayVersion;
1578     IDiscordStorageEvents* storageEvents;
1579     DiscordVersion storageVersion;
1580     IDiscordStoreEvents* storeEvents;
1581     DiscordVersion storeVersion;
1582     IDiscordVoiceEvents* voiceEvents;
1583     DiscordVersion voiceVersion;
1584     IDiscordAchievementEvents* achievementEvents;
1585     DiscordVersion achievementVersion;
1586 }
1587 
1588 void DiscordCreateParamsSetDefault(DiscordCreateParams* params)
1589 {
1590     memset(params, 0, DiscordCreateParams.sizeof);
1591     params.applicationVersion = DISCORD_APPLICATION_MANAGER_VERSION;
1592     params.userVersion = DISCORD_USER_MANAGER_VERSION;
1593     params.imageVersion = DISCORD_IMAGE_MANAGER_VERSION;
1594     params.activityVersion = DISCORD_ACTIVITY_MANAGER_VERSION;
1595     params.relationshipVersion = DISCORD_RELATIONSHIP_MANAGER_VERSION;
1596     params.lobbyVersion = DISCORD_LOBBY_MANAGER_VERSION;
1597     params.networkVersion = DISCORD_NETWORK_MANAGER_VERSION;
1598     params.overlayVersion = DISCORD_OVERLAY_MANAGER_VERSION;
1599     params.storageVersion = DISCORD_STORAGE_MANAGER_VERSION;
1600     params.storeVersion = DISCORD_STORE_MANAGER_VERSION;
1601     params.voiceVersion = DISCORD_VOICE_MANAGER_VERSION;
1602     params.achievementVersion = DISCORD_ACHIEVEMENT_MANAGER_VERSION;
1603 }
1604 
1605 DiscordResult DiscordCreate(DiscordVersion ver, DiscordCreateParams * params, IDiscordCore** result);